﻿using System.Collections.Generic;
using PT.Common;

namespace PT.Timing {

    /// <summary>
    /// A sorted list of clicks. Clicks are sorted by their noteDuration values from largest to smallest
    /// </summary>
    public class ClickList : IEnumerable<Click> {

        /// <summary> Contains Click object as key and intrinsic state (last click time) as value</summary>
        readonly List<Click> clicks;

        public ClickList() {
            clicks = new List<Click>();

        }

        public void Add(Rational noteDuration) {
            var click = new Click(noteDuration);

            Add(click);
        }

        public void Add(Click click) {
            var index = clicks.BinarySearch(click, ClickDescOrderComparer.Instance);
            if (index < 0) {
                clicks.Insert(~index, click);
            }
        }

        public void Remove(Rational noteDuration) {
            var click = new Click(noteDuration);

            Remove(click);
        }

        public void Remove(Click click) {
            int index = clicks.BinarySearch(click, ClickDescOrderComparer.Instance);

            if (index < 0) {
                return;
            }

            clicks.RemoveAt(index);
        }

        public Click this[int index] {
            get { return clicks[index]; }
        }
        public int Count {
            get { return clicks.Count; }
        }

        internal static ClickList BuildDefaultClickList() {
            var result = new ClickList {
                new Rational(1, 4) //, new Rational(1, 8), new Rational(1, 16)
            };

            return result;
        }

        public IEnumerator<Click> GetEnumerator() {
            for (int i = 0; i < clicks.Count; ++i) {
                yield return clicks[i];
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }

        class ClickDescOrderComparer : IComparer<Click> {

            public int Compare(Click x, Click y) {
                return -x.CompareTo(y);
            }

            static readonly ClickDescOrderComparer instance = new ClickDescOrderComparer();
            public static ClickDescOrderComparer Instance { get { return instance; } }
        }

    }
}
